/*
  Team 17
 */

#include "dominion.h"
#include <stdio.h>
#include "rngs.h"
#include <stdlib.h>
#include <time.h>
#include "interface.c"
#include <string.h>

#define MAX_K_CARDS 10
#define MAX_PLAYERS 4
#define MIN_PLAYERS 2
#define MAX_CARD_NAME 12
#define MAX_SEED 2147483647
#define MAX_ATTEMPTS 1000

// generates a random num with given range and offset
int randomNum(int range, int offset){
  return (rand() % (range + 1)) + offset;
}

// check if in array
int inArray(int *list, int num, int length){
  int i;

  for(i = 0; i < length; i++){
    if(list[i] == num){
      //printf("in array\n");
      return 1;
    }
  }
  return 0;
}

// generates an array of 10 random kingdom cards 
int* randKingCards(void){
  int *cards, i, randCard;
  int range = treasure_map - adventurer; // (26 - 7 = 19?)
  //printf("range: %d\n", range);
  
  cards = malloc(MAX_K_CARDS * sizeof(int));

  while(i < MAX_K_CARDS){
    randCard = randomNum(range, adventurer);
    
    //printf("randCard: |%d|\n", randCard);

    if(i == 0 || (inArray(cards, randCard, MAX_K_CARDS) == 0)){
      cards[i] = randCard;
      //printf("array cards[%d]: %d\n", i, cards[i]);
      i++;
    }
  }

  return cards;
}

int testGame(int details){
  int *k = malloc(MAX_K_CARDS * sizeof(int));;
  int i = 0, numPlayers, money = 0, randomSeed, attempts, choice1, choice2, choice3, randCard;
  struct gameState state;
  time_t tm;
  srand((unsigned) time(&tm));
  char cardName[MAX_CARD_NAME];
  
  // random kingdom cards
  k = randKingCards();

  // create random seed
  randomSeed = (rand() % MAX_SEED) - 1;
  
  // randomize number of players
  numPlayers = randomNum(MAX_PLAYERS - MIN_PLAYERS, MIN_PLAYERS);
  
  // initialize game
  initializeGame(numPlayers, k, randomSeed, &state);
  
  if(details){
    printf("Testing Dominion Game with %d players and the following kingdom cards:\n", numPlayers);
    for(i = 0; i < MAX_K_CARDS; i++){
      cardNumToName(k[i], cardName);
      printf("Card[%d]: %s\n", (i+1), cardName);
    }
    printf("\n");
  }  

  while(!isGameOver(&state)){
    money = 0;

    if(details)
      printf("-------------Player %d's turn.-------------\n", (state.whoseTurn + 1));
    
    i = 0;
    while(i < numHandCards(&state)){
      if(handCard(i, &state) == copper){
	money++;
      } else if(handCard(i, &state) == silver){
	money += 2;
      } else if(handCard(i, &state) == gold){
	money += 3;
      }
      i++;
    }
    if(details)
      printf("Money: %d\n", money);
    
    choice1 = rand() % 27;
    choice2 = rand() % 27;
    choice3 = rand() % 27;

    
    // play cards
    i = 0;
    attempts = 0;
    while(i < numHandCards(&state)){
      // randomly choose to play this card
      if(handCard(i, &state) > gold && (rand() % 2) == 0){
	while(playCard(i, choice1, choice2, choice3, &state) == -1 && attempts < MAX_ATTEMPTS){
	  choice1 = rand() % 27;
	  choice2 = rand() % 27;
	  choice3 = rand() % 27;
	  attempts++;
	}
      }
      i++;
    }

    if(attempts >= MAX_ATTEMPTS)
      printf("Failed to play card\n");
	
    attempts = 0;
    // randomly each turn to buy a random card
    if(money >= 3){
      if(rand() % 2 == 0){
	randCard = (rand() % 20) + 6;
	while(buyCard(randCard, &state) == -1 && attempts < MAX_ATTEMPTS){
	  randCard = (rand() % 20) + 6;
	  attempts++;
	}
      }
    }

    if(attempts >= MAX_ATTEMPTS)
      printf("Failed to buy card\n");

    // buy victory or treasure cards
    if(money >= 8){
      buyCard(province, &state);
      if(details)
	printf("Bought province\n");
    } else if(money >= 6){
      buyCard(gold, &state);
      if(details)
	printf("Bought gold\n");
    } else if(money >= 4){
      buyCard(gardens, &state);
      if(details)
	printf("Bought gardens\n");
    } else if(money >= 3){
      buyCard(silver, &state);
      if(details)
	printf("Bought silver\n");
    }
    if(details)
      printf("----------Player %d's turn has ended--------\n\n", (state.whoseTurn + 1));
    endTurn(&state);
    
  }
  if(details)
    printf("\nGame has concluded\n");
  
  for(i = 0; i < numPlayers; i++){
    if(details)
      printf("Player %d's score: %d\n", (i+1), scoreFor(i, &state));
  }
  
  return 0;
}

void argumentInfo(void){
  printf("Please specify no arguments for one game without details\n");
  printf("or specify '-d' for one game with details\n");
  printf("or specify '-n' followed by the # of tests to perform without details\n");
}

int main (int argc, char** argv){
  int numTests, i, success = 0;
  
  if(argc < 2){
    // run one test without details, default
    testGame(0);
    printf("Game ran successfully\n");
  } else if(argc < 3){
    if(strcmp(argv[1], "-d") == 0){
      // run one test with details
      testGame(1);
    } else {
      argumentInfo();
    }
  } else if(argc == 3){
    if(strcmp(argv[1], "-n") == 0){
      if((numTests = atoi(argv[2])) != 0){
	// run however many games
	for(i = 0; i < numTests; i++){
	  if(testGame(0) == 0)
	    success++;
	}
	printf("Successfully ran %d random games of dominion\n", success);
      }
    }  else {
      argumentInfo();
    }
  } else {
    argumentInfo();
  }
  
  return 0;
}


